package com.codehelper;

import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.ITypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.select.BranchBuilder;
import com.baomidou.mybatisplus.generator.config.converts.select.Selector;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;

/**
 * @author xieqiang
 * @date 2023/5/9
 * @since java 1.8
 */
public class CustomOracleTypeConvert implements ITypeConvert {

    public IColumnType processTypeConvert(GlobalConfig config, String fieldType) {
        return (IColumnType) use(fieldType).test(containsAny(new CharSequence[]{"char", "clob"}).then(DbColumnType.STRING)).test(containsAny(new CharSequence[]{"date", "timestamp"}).then((p) -> {
            return toDateType(config);
        })).test(contains("number").then(CustomOracleTypeConvert::toNumberType)).test(contains("float").then(DbColumnType.FLOAT)).test(contains("blob").then(DbColumnType.BLOB)).test(containsAny(new CharSequence[]{"binary", "raw"}).then(DbColumnType.BYTE_ARRAY)).or(DbColumnType.STRING);
    }

    private static IColumnType toNumberType(String typeName) {
        if(typeName.equals("number")){
            return DbColumnType.LONG;
        }
        if (typeName.matches("number\\([0-9]\\)")) {
            return DbColumnType.INTEGER;
        }else if(typeName.matches("number\\(\\*\\)")){
            return DbColumnType.LONG;
        }else {
            return typeName.matches("number\\(1[0-8]\\)") ? DbColumnType.LONG : DbColumnType.BIG_DECIMAL;
        }
    }

    protected static IColumnType toDateType(GlobalConfig config) {
        switch (config.getDateType()) {
            case ONLY_DATE:
                return DbColumnType.DATE;
            case SQL_PACK:
                return DbColumnType.TIMESTAMP;
            case TIME_PACK:
                return DbColumnType.LOCAL_DATE_TIME;
            default:
                return DbColumnType.STRING;
        }
    }

    static Selector<String, IColumnType> use(String param) {
        return new Selector(param.toLowerCase());
    }

    static BranchBuilder<String, IColumnType> contains(CharSequence value) {
        return BranchBuilder.of((s) -> {
            return s.contains(value);
        });
    }

    static BranchBuilder<String, IColumnType> containsAny(CharSequence... values) {
        return BranchBuilder.of((s) -> {
            CharSequence[] var2 = values;
            int var3 = values.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                CharSequence value = var2[var4];
                if (s.contains(value)) {
                    return true;
                }
            }

            return false;
        });
    }
}
